package com.sharer.last.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sharer.last.base.enums.BusinessExceptionCode;
import com.sharer.last.base.enums.ExceptionPrefixParamEnum;
import com.sharer.last.base.enums.SiteSettingTypeEnum;
import com.sharer.last.base.exception.BusinessException;
import com.sharer.last.base.utils.CollectionUtil;
import com.sharer.last.enums.SiteSettingTagEnum;
import com.sharer.last.model.dto.sitesetting.SiteSettingChangeDTO;
import com.sharer.last.model.dto.sitesetting.SiteSettingUpdateDTO;
import com.sharer.last.model.vo.siteSetting.*;
import com.sharer.last.utils.BeanUtil;
import com.sharer.last.utils.json.JsonUtil;
import com.sharer.last.utils.markdown.MarkdownUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.sharer.last.constant.SiteSettingConstants;
import com.sharer.last.model.po.SiteSettingPO;
import com.sharer.last.mapper.SiteSettingMapper;
import com.sharer.last.service.SiteSettingService;
import com.sharer.last.utils.JacksonUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 站点设置业务层实现
 *
 * @ClassName SiteSettingServiceImpl
 * @Author wangjin
 * @Date 2023/5/5 20:45
 * @Description
 * @Version 1.0
 */
@Service
public class SiteSettingServiceImpl extends ServiceImpl<SiteSettingMapper, SiteSettingPO> implements SiteSettingService {
    @Resource
    SiteSettingMapper siteSettingMapper;

    private static final Pattern PATTERN = Pattern.compile("\"(.*?)\"");

    /**
     * 查询网页标题后缀
     *
     * @return
     */
    @Override
    public String getWebTitleSuffix() {
        LambdaQueryWrapper<SiteSettingPO> qw = new LambdaQueryWrapper<>();
        qw.eq(SiteSettingPO::getTagType, SiteSettingTagEnum.WEB_TITLE_SUFFIX.getTagType());
        SiteSettingPO one = this.getOne(qw, false);
        if (one == null) {
            return "";
        }
        return one.getNameZh();
    }

    /**
     * 获取站点配置信息
     *
     * @return
     */
    @Override
    public SiteSettingIndexVO getSiteInfo() {
        List<SiteSettingPO>                          list         = this.list();
        SiteSettingIndexVO.SiteSettingIndexVOBuilder builder      = SiteSettingIndexVO.builder();
        Map<String, String>                          siteInfo     = new HashMap<>();
        List<BadgeVO>                                badges       = new ArrayList<>();
        IntroductionVO                               introduction = new IntroductionVO();
        List<FavoriteVO>                             favorites    = new ArrayList<>();
        List<String>                                 rollTexts    = new ArrayList<>();
        for (SiteSettingPO siteSettingPO : list) {
            switch (siteSettingPO.getSiteSettingType()) {
                case 1:
                    if (SiteSettingConstants.COPYRIGHT.equals(siteSettingPO.getNameEn())) {
                        CopyrightVO copyright = BeanUtil.copy(siteSettingPO.getValue(), CopyrightVO.class);
                        builder.copyright(copyright);
                    } else {
                        siteInfo.put(siteSettingPO.getNameEn(), siteSettingPO.getValue());
                    }
                    break;
                case 2:
                    switch (siteSettingPO.getNameEn()) {
                        case SiteSettingConstants.AVATAR:
                            introduction.setAvatar(siteSettingPO.getValue());
                            break;
                        case SiteSettingConstants.NAME:
                            introduction.setName(siteSettingPO.getValue());
                            break;
                        case SiteSettingConstants.GITHUB:
                            introduction.setGithub(siteSettingPO.getValue());
                            break;
                        case SiteSettingConstants.TELEGRAM:
                            introduction.setTelegram(siteSettingPO.getValue());
                            break;
                        case SiteSettingConstants.QQ:
                            introduction.setQq(siteSettingPO.getValue());
                            break;
                        case SiteSettingConstants.BILIBILI:
                            introduction.setBilibili(siteSettingPO.getValue());
                            break;
                        case SiteSettingConstants.NETEASE:
                            introduction.setNetease(siteSettingPO.getValue());
                            break;
                        case SiteSettingConstants.EMAIL:
                            introduction.setEmail(siteSettingPO.getValue());
                            break;
                        case SiteSettingConstants.ROLL_TEXT:
                            Matcher m = PATTERN.matcher(siteSettingPO.getValue());
                            while (m.find()) {
                                rollTexts.add(m.group(1));
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                case 4:
                    BadgeVO badge = JacksonUtils.readValue(siteSettingPO.getValue(), BadgeVO.class);
                    badges.add(badge);
                    break;
                case 5:
                    FavoriteVO favorite = JsonUtil.parse(siteSettingPO.getValue(),FavoriteVO.class);
                    favorites.add(favorite);
                    break;
                default:
                    break;
            }
        }
        introduction.setRollText(rollTexts);
        introduction.setFavorites(favorites);
        return builder.siteInfo(siteInfo)
                .badges(badges)
                .favorites(favorites)
                .rollTexts(rollTexts)
                .introduction(introduction).build();

    }

    /**
     * 获取友链信息
     *
     * @param md 是否未markdown语法格式 true：是
     * @return
     */
    @Override
    public FriendInfoVO getFriendInfo(boolean md) {
        FriendInfoVO                      friendInfo  = new FriendInfoVO();
        LambdaQueryWrapper<SiteSettingPO> qw          = new LambdaQueryWrapper<>();
        List<Integer>                     tagTypeList = new ArrayList<>();
        tagTypeList.add(20);
        tagTypeList.add(21);
        qw.in(SiteSettingPO::getTagType, tagTypeList);
        List<SiteSettingPO> list = this.list(qw);
        for (SiteSettingPO siteSettingPO : list) {
            Integer tagType = siteSettingPO.getTagType();
            if (tagType == 20) {
                if (md) {
                    friendInfo.setContent(MarkdownUtils.markdownToHtmlExtensions(siteSettingPO.getValue()));
                } else {
                    friendInfo.setContent(siteSettingPO.getValue());
                }
            } else {
                if ("1".equals(siteSettingPO.getValue())) {
                    friendInfo.setCommentEnabled(true);
                } else {
                    friendInfo.setCommentEnabled(false);
                }
            }
        }
        return friendInfo;
    }

    /**
     * 根据类型分组
     *
     * @return
     */
    @Override
    public Map<String, List<SiteSettingPO>> selectAllListByTypeGrouping() {
        LambdaQueryWrapper<SiteSettingPO> qw = new LambdaQueryWrapper<>();
        List<SiteSettingPO> list = this.list(qw);
        if (CollectionUtil.isEmpty(list)) {
            return SiteSettingTagEnum.getMap();
        }
        Map<String, List<SiteSettingPO>> map         = new HashMap<>();
        List<SiteSettingPO>              baseSetting = list.stream().filter(f -> f.getSiteSettingType() == 1).collect(Collectors.toList());
        List<SiteSettingPO>              dataCard    = list.stream().filter(f -> f.getSiteSettingType() == 2).collect(Collectors.toList());
        List<SiteSettingPO>              friend      = list.stream().filter(f -> f.getSiteSettingType() == 3).collect(Collectors.toList());
        List<SiteSettingPO>              badge       = list.stream().filter(f -> f.getSiteSettingType() == 4).collect(Collectors.toList());
        List<SiteSettingPO>              favorite    = list.stream().filter(f -> f.getSiteSettingType() == 5).collect(Collectors.toList());
        map.put(SiteSettingTypeEnum.BASE_SETTING.getNameEn(), baseSetting);
        map.put(SiteSettingTypeEnum.DATA_CARD.getNameEn(), dataCard);
        map.put(SiteSettingTypeEnum.FRIEND_INFO.getNameEn(), friend);
        map.put(SiteSettingTypeEnum.BADGE.getNameEn(), badge);
        map.put(SiteSettingTypeEnum.FAVORITE.getNameEn(), favorite);
        return map;

    }

    /**
     * 更新站点配置信息
     *
     * @param siteSettingUpdateDTO
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateAllSiteSetting(SiteSettingUpdateDTO siteSettingUpdateDTO) {
        // 删除指定配置信息
        List<Long> deletedIds = siteSettingUpdateDTO.getDeletedIds();
        if (CollectionUtil.isNotEmpty(deletedIds)) {
            if (!this.removeBatchByIds(deletedIds)) {
                throw new BusinessException(BusinessExceptionCode.DATA_REMOVE_FAIL, ExceptionPrefixParamEnum.SITE_SETTING);
            }
        }

        // 新增或编辑
        List<SiteSettingChangeDTO> list = siteSettingUpdateDTO.getList();
        if (CollectionUtil.isNotEmpty(list)) {
            List<SiteSettingPO> poList = list.stream().map(m -> {
                SiteSettingPO siteSettingPO = BeanUtil.copy(m, SiteSettingPO.class);
                return siteSettingPO;
            }).collect(Collectors.toList());
            if (!this.saveOrUpdateBatch(poList)) {
                throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.SITE_SETTING);
            }
        }
    }

    /**
     * 修改友链页面评论开放状态
     *
     * @param commentEnabled
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateFriendCommentEnabled(Integer commentEnabled) {
        LambdaQueryWrapper<SiteSettingPO> qw = new LambdaQueryWrapper<>();
        qw.eq(SiteSettingPO::getTagType, SiteSettingTagEnum.FRIEND_COMMENT_ENABLED.getTagType());
        SiteSettingPO siteSettingPO = SiteSettingPO.builder()
                .value(commentEnabled + "")
                .build();
        if (!this.update(siteSettingPO, qw)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.SITE_SETTING);
        }
    }

    /**
     * 修改友链页面评论开放状态
     *
     * @param content
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateFriendContent(String content) {
        LambdaQueryWrapper<SiteSettingPO> qw = new LambdaQueryWrapper<>();
        qw.eq(SiteSettingPO::getTagType, SiteSettingTagEnum.FRIEND_CONTENT.getTagType());
        SiteSettingPO siteSettingPO = SiteSettingPO.builder()
                .value(content)
                .build();
        if (!this.update(siteSettingPO, qw)) {
            throw new BusinessException(BusinessExceptionCode.DATA_UPDATE_FAIL, ExceptionPrefixParamEnum.SITE_SETTING);
        }
    }
}
